package org.example.misc.config;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * ContentCachingRequestWrapper 中body 没有读取缓存，只能读取一次   https://github.com/spring-projects/spring-framework/issues/17083
 */

@Slf4j
public class LogFilter extends OncePerRequestFilter {


    /**
     * 上传文件
     * 下载文件
     *
     * @param request  requestId 接口传入
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        RepeatableRequestWrapper requestWrapper = new RepeatableRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
        String requestId = responseWrapper.getHeader("requestId");
        String params;
        if ("GET".equals(requestWrapper.getMethod())) {
            params = requestWrapper.getQueryString();
        } else {
            if (!"application/json".equals(requestWrapper.getContentType())) {
                params = "body is not application/json,don't show";
            } else {
                params = obtainRequestBody(requestWrapper.getInputStream());
            }
        }
        filterChain.doFilter(requestWrapper, responseWrapper);
        log.info("Request id:{}; Method:{}; Path:{}; ContentType:{}; URI:{}; Param:{}",
                requestId,
                requestWrapper.getMethod(),
                requestWrapper.getServletPath(),
                requestWrapper.getContentType(),
                requestWrapper.getRequestURI(), params);
        String string = IOUtils.toString(responseWrapper.getContentInputStream(), StandardCharsets.UTF_8);
        log.info("Response id:{}; status:{} ;body{}", requestId, response.getStatus(), string);
        responseWrapper.copyBodyToResponse();
    }

    private String obtainRequestBody(ServletInputStream inputStream) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String str = "";
        String wholeStr = "";
        //一行一行的读取body体里面的内容
        while ((str = reader.readLine()) != null) {
            wholeStr += str;
        }
        return wholeStr;
    }
}
